// 全局变量
let sudokuBoard = Array(9).fill().map(() => Array(9).fill(0));
let originalBoard = Array(9).fill().map(() => Array(9).fill(0));
let solvingSteps = [];
let currentStepIndex = 0;
let selectedCell = { row: -1, col: -1 };
let appConfig = {
    baiduOcr: {
        apiKey: '',
        secretKey: ''
    },
    ocrEngine: 'tesseract'
};

// DOM 元素
let boardElement, solveBtn, clearBtn, checkBtn, difficultyDisplay, statusMessage, stepControls;
let prevStepBtn, nextStepBtn, stepCounter, imageInput, previewImage, settingsBtn, fileUpload;
let sudokuGridContainer, operationButtons, uploadArea, imagePreviewContainer;
let stepByStepBtn, imagePreview, friendlyAlert, alertMessage, closeAlert, confirmAlert, manualInputBtn;
let generateBtn; // 新增的随机生成按钮

// 初始化数独网格
function initializeSudokuBoard() {
    console.log("initializeSudokuBoard 被调用");
    // 获取DOM元素
    boardElement = document.getElementById('sudokuBoard');
    solveBtn = document.getElementById('solveBtn');
    clearBtn = document.getElementById('clearBtn');
    checkBtn = document.getElementById('checkBtn');
    difficultyDisplay = document.getElementById('difficultyDisplay');
    statusMessage = document.getElementById('statusMessage');
    stepControls = document.getElementById('stepControls');
    prevStepBtn = document.getElementById('prevStepBtn');
    nextStepBtn = document.getElementById('nextStepBtn');
    stepCounter = document.getElementById('stepCounter');
    imageInput = document.getElementById('imageInput');
    previewImage = document.getElementById('previewImage');
    settingsBtn = document.getElementById('settingsBtn');
    fileUpload = document.getElementById('file-upload');
    sudokuGridContainer = document.getElementById('sudokuGridContainer');
    operationButtons = document.getElementById('operationButtons');
    uploadArea = document.getElementById('uploadArea');
    imagePreviewContainer = document.getElementById('imagePreviewContainer');
    generateBtn = document.getElementById('generateBtn'); // 获取随机生成按钮
    
    console.log("DOM元素获取完成", { boardElement, solveBtn, clearBtn });
    
    // 创建棋盘
    createBoard();
    
    // 设置事件监听器
    setupEventListeners();
}

// 初始化
document.addEventListener('DOMContentLoaded', function() {
    console.log("DOM fully loaded and parsed");
    
    // 页面加载时自动加载配置
    fetch('config.php')
        .then(response => response.json())
        .then(config => {
            console.log('App加载的配置:', config);  // 添加调试信息
            appConfig = config;
        })
        .catch(error => {
            console.error('从服务器加载配置失败:', error);
        });
});

// 创建数独棋盘
function createBoard() {
    console.log("createBoard 被调用");
    if (!boardElement) {
        boardElement = document.getElementById('sudokuBoard');
    }
    
    if (!boardElement) {
        console.error("无法找到数独棋盘元素");
        return;
    }
    
    boardElement.innerHTML = '';
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            const cell = document.createElement('div');
            // 添加适当的CSS类以确保单元格在网格中正确显示
            cell.className = 'flex items-center justify-center border border-gray-400 relative bg-white aspect-square';
            cell.dataset.row = row;
            cell.dataset.col = col;
            
            // 添加边框以区分3x3子网格
            if (row % 3 === 0) {
                cell.classList.add('border-t-2', 'border-t-gray-800');
            }
            if (col % 3 === 0) {
                cell.classList.add('border-l-2', 'border-l-gray-800');
            }
            if (row === 8) {
                cell.classList.add('border-b-2', 'border-b-gray-800');
            }
            if (col === 8) {
                cell.classList.add('border-r-2', 'border-r-gray-800');
            }
            
            const input = document.createElement('input');
            input.type = 'tel'; // 使用tel类型在移动设备上显示数字键盘
            input.inputMode = 'numeric'; // 确保显示数字键盘
            input.maxLength = 1;
            input.classList.add('w-full', 'h-full', 'text-center', 'text-2xl', 'p-0', 'm-0', 'focus:outline-none', 'focus:ring-0', 'bg-transparent', 'border-0');
            
            input.addEventListener('input', (e) => handleInput(e, row, col));
            input.addEventListener('keydown', (e) => handleKeyDown(e, row, col));
            input.addEventListener('focus', () => selectCell(row, col));
            
            cell.appendChild(input);
            boardElement.appendChild(cell);
        }
    }
    
    console.log("数独棋盘创建完成");
}

// 设置事件监听器
function setupEventListeners() {
    console.log("设置事件监听器", { solveBtn, clearBtn, checkBtn, generateBtn });
    if (solveBtn) solveBtn.addEventListener('click', solveSudoku);
    if (clearBtn) clearBtn.addEventListener('click', clearBoard);
    if (checkBtn) checkBtn.addEventListener('click', checkErrors);
    if (prevStepBtn) prevStepBtn.addEventListener('click', showPrevStep);
    if (nextStepBtn) nextStepBtn.addEventListener('click', showNextStep);
    if (settingsBtn) settingsBtn.addEventListener('click', () => {
        window.location.href = 'settings.html';
    });
    // 添加随机生成按钮事件监听器
    if (generateBtn) generateBtn.addEventListener('click', function(event) {
        event.preventDefault(); // 阻止默认行为，防止页面跳转
        generateRandomSudoku();
    });
    
    console.log("事件监听器设置完成");
}

// 处理输入
function handleInput(e, row, col) {
    const value = e.target.value;
    if (value === '' || (value >= '1' && value <= '9')) {
        sudokuBoard[row][col] = value === '' ? 0 : parseInt(value);
        // 显示数独网格
        sudokuGridContainer.classList.remove('hidden');
        // 显示操作按钮
        operationButtons.classList.remove('hidden');
        updateBoardDisplay();
        updateDifficulty();
    } else {
        e.target.value = '';
        sudokuBoard[row][col] = 0;
    }
}

// 处理键盘事件
function handleKeyDown(e, row, col) {
    // 允许方向键导航
    switch (e.key) {
        case 'ArrowUp':
            if (row > 0) selectCell(row - 1, col);
            break;
        case 'ArrowDown':
            if (row < 8) selectCell(row + 1, col);
            break;
        case 'ArrowLeft':
            if (col > 0) selectCell(row, col - 1);
            break;
        case 'ArrowRight':
            if (col < 8) selectCell(row, col + 1);
            break;
        default:
            // 其他按键按正常处理
            break;
    }
}

// 选择单元格
function selectCell(row, col) {
    // 移除之前选中单元格的样式
    document.querySelectorAll('[data-row][data-col]').forEach(cell => {
        cell.classList.remove('bg-blue-100', 'shadow-inner');
    });
    
    // 添加新选中单元格的样式
    const cell = document.querySelector(`[data-row="${row}"][data-col="${col}"]`);
    if (cell) {
        cell.classList.add('bg-blue-100');
        selectedCell = { row, col };
        
        // 聚焦到输入框
        const input = cell.querySelector('input');
        if (input) {
            input.focus();
        }
    }
}

// 更新棋盘显示
function updateBoardDisplay() {
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            const cell = document.querySelector(`[data-row="${row}"][data-col="${col}"]`);
            const input = cell.querySelector('input');
            const value = sudokuBoard[row][col];
            
            input.value = value === 0 ? '' : value;
            
            // 更新样式类
            input.classList.remove('bg-gray-200', 'text-gray-800', 'text-red-600', 'text-blue-600', 'text-green-600', 'font-bold', 'text-gray-400');
            
            // 区分三种情况：
            // 1. OCR识别填充的题目数字 - 黑色粗体
            // 2. 手工输入的题目数字 - 浅灰不加粗
            // 3. 程序求解得出的数字 - 蓝色不加粗
            if (value !== 0) {
                if (originalBoard[row][col] !== 0 && originalBoard[row][col] === sudokuBoard[row][col]) {
                    // OCR识别填充的题目数字 - 黑色粗体
                    input.classList.add('text-gray-800', 'font-bold');
                } else if (originalBoard[row][col] !== 0 && originalBoard[row][col] !== sudokuBoard[row][col]) {
                    // 程序求解得出的数字 - 蓝色不加粗
                    input.classList.add('text-blue-600');
                } else if (originalBoard[row][col] === 0) {
                    // 手工输入的题目数字 - 浅灰不加粗
                    input.classList.add('text-gray-400');
                } else {
                    // 默认情况（应该是求解得出的数字）- 蓝色不加粗
                    input.classList.add('text-blue-600');
                }
            }
        }
    }
}

// 更新难度显示
function updateDifficulty() {
    const difficulty = evaluateDifficulty(sudokuBoard);
    difficultyDisplay.textContent = `难度: ${difficulty}`;
}

// 更新状态消息显示
function updateStatusMessage(content, className = '', autoHide = false, hideDelay = 5000) {
    if (statusMessage && content) {
        statusMessage.innerHTML = content;
        if (className) {
            statusMessage.className = className;
        }
        // 显示提示信息区域
        const hintArea = document.getElementById('hintArea');
        if (hintArea) hintArea.classList.remove('hidden');
        
        // 如果需要自动隐藏，设置定时器
        if (autoHide) {
            setTimeout(() => {
                statusMessage.textContent = '';
                if (hintArea) hintArea.classList.add('hidden');
            }, hideDelay);
        }
    } else if (statusMessage) {
        statusMessage.textContent = '';
        // 隐藏提示信息区域
        const hintArea = document.getElementById('hintArea');
        if (hintArea) hintArea.classList.add('hidden');
    }
}

// 显示Toast消息
function showToast(message, type = 'info', duration = 3000) {
    const toastContainer = document.getElementById('toastContainer');
    
    // 创建Toast元素
    const toast = document.createElement('div');
    toast.className = `toast ${type} show`;
    toast.innerHTML = message;
    
    // 添加到容器
    toastContainer.appendChild(toast);
    
    // 设置定时器自动移除
    setTimeout(() => {
        toast.classList.remove('show');
        setTimeout(() => {
            if (toast.parentNode) {
                toast.parentNode.removeChild(toast);
            }
        }, 300);
    }, duration);
}

// 显示手动录入界面
function showManualInput(event) {
    console.log("手动录入按钮被点击，事件对象:", event);
    // 阻止默认行为（如果有）
    if (event) {
        event.preventDefault();
    }
    
    try {
        // 隐藏上传区域
        uploadArea.classList.add('hidden');
        // 显示数独网格
        sudokuGridContainer.classList.remove('hidden');
        // 显示操作按钮
        operationButtons.classList.remove('hidden');
        
        // 清空棋盘但不隐藏网格和按钮
        sudokuBoard = Array(9).fill().map(() => Array(9).fill(0));
        originalBoard = Array(9).fill().map(() => Array(9).fill(0));
        updateBoardDisplay();
        updateStatusMessage('', '');
        difficultyDisplay.textContent = '难度: 未知';
        stepControls.classList.add('hidden');
        clearErrors();
        
        // 聚焦到第一个单元格
        selectCell(0, 0);
        
        // 添加状态提示
        updateStatusMessage('<i class="fas fa-info-circle mr-2"></i>已进入手动录入模式，请在数独网格中输入数字', 'status-message text-blue-600 info-message');
        
        // 显示Toast提示
        showToast('<i class="fas fa-info-circle mr-2"></i>已进入手动录入模式，请在数独网格中输入数字', 'info');
        
        // 添加视觉反馈，让用户知道已经进入手动录入模式
        setTimeout(() => {
            sudokuGridContainer.classList.add('animate-pulse-border');
            setTimeout(() => {
                sudokuGridContainer.classList.remove('animate-pulse-border');
            }, 1000);
        }, 100);
        
        console.log("手动录入功能执行完成");
    } catch (error) {
        console.error("手动录入功能执行出错:", error);
    }
}

// 求解数独
function solveSudoku() {
    // 清除状态提示
    updateStatusMessage('', '');
    
    // 隐藏图片预览
    imagePreviewContainer.classList.add('hidden');
    
    updateStatusMessage('<i class="fas fa-circle-notch fa-spin mr-2"></i>正在求解...', 'status-message text-blue-600 info-message');
    
    // 模拟求解延迟
    setTimeout(() => {
        // 注意：在OCR识别或手动输入时，原始棋盘已经设置
        // 这里不需要再保存原始棋盘，否则会将用户输入的数字也视为原始题目数字
        
        // 检查数独是否有效
        if (!isValidSudoku(sudokuBoard)) {
            updateStatusMessage('<i class="fas fa-exclamation-circle mr-2"></i>数独题目无效，请检查输入', 'status-message text-red-600 text-lg error-message');
            return;
        }
        
        // 创建棋盘副本进行求解
        const boardCopy = JSON.parse(JSON.stringify(sudokuBoard));
        
        if (solveSudokuAlgorithm(boardCopy)) {
            // 求解成功
            sudokuBoard = boardCopy;
            updateBoardDisplay();
            updateStatusMessage('<i class="fas fa-check-circle mr-2"></i>数独求解完成！', 'status-message text-green-600 text-lg success-message', true, 3000);
        } else {
            // 无解
            updateStatusMessage('<i class="fas fa-exclamation-circle mr-2"></i>数独无解！', 'status-message text-red-600 text-lg error-message');
        }
        
        // 隐藏逐步求解控件
        stepControls.classList.add('hidden');
    }, 800); // 模拟800毫秒的求解延迟
}

// 逐步求解数独
function solveStepByStep() {
    // 注意：在OCR识别或手动输入时，原始棋盘已经设置
    // 这里不需要再保存原始棋盘，否则会将用户输入的数字也视为原始题目数字
    
    // 检查数独是否有效
    if (!isValidSudoku(sudokuBoard)) {
        updateStatusMessage('<i class="fas fa-exclamation-circle mr-2"></i>数独题目无效，请检查输入', 'status-message text-red-600 text-lg error-message');
        return;
    }
    
    // 获取求解步骤
    solvingSteps = solveSudokuStepByStepAlgorithm(sudokuBoard);
    
    if (solvingSteps.length > 0) {
        currentStepIndex = 0;
        updateStatusMessage('<i class="fas fa-circle-notch fa-spin mr-2"></i>开始逐步求解...', 'status-message text-blue-600 text-lg info-message');
        stepControls.classList.remove('hidden');
        updateStepCounter();
    } else {
        updateStatusMessage('<i class="fas fa-exclamation-circle mr-2"></i>无法生成求解步骤', 'status-message text-red-600 text-lg error-message');
    }
}

// 显示上一步
function showPrevStep() {
    if (currentStepIndex > 0) {
        currentStepIndex--;
        applyStep(currentStepIndex);
        updateStepCounter();
    }
}

// 显示下一步
function showNextStep() {
    if (currentStepIndex < solvingSteps.length - 1) {
        applyStep(currentStepIndex);
        currentStepIndex++;
        updateStepCounter();
    } else if (currentStepIndex === solvingSteps.length - 1) {
        // 最后一步, 完成求解
        applyStep(currentStepIndex);
        currentStepIndex++;
        updateStepCounter();
        updateStatusMessage('<i class="fas fa-check-circle mr-2"></i>逐步求解完成！', 'status-message text-green-600 text-lg success-message');
    }
}

// 应用步骤
function applyStep(stepIndex) {
    const step = solvingSteps[stepIndex];
    if (step.action === 'try' || step.action === 'backtrack') {
        sudokuBoard[step.row][step.col] = step.num;
        updateBoardDisplay();
    }
}

// 更新步骤计数器
function updateStepCounter() {
    stepCounter.textContent = `步骤 ${currentStepIndex}/${solvingSteps.length}`;
    prevStepBtn.disabled = currentStepIndex === 0;
    nextStepBtn.disabled = currentStepIndex === solvingSteps.length;
}

// 检查错误
function checkErrors() {
    const errors = findSudokuErrors(sudokuBoard);
    clearErrors();
    
    if (errors.length > 0) {
        errors.forEach(error => {
            const cell = document.querySelector(`[data-row="${error.row}"][data-col="${error.col}"]`);
            if (cell) {
                cell.classList.add('bg-red-200');
            }
        });
        updateStatusMessage(`<i class="fas fa-exclamation-circle mr-2"></i>发现 ${errors.length / 2} 处错误`, 'status-message text-red-600 text-lg error-message');
    } else {
        updateStatusMessage('<i class="fas fa-check-circle mr-2"></i>未发现错误', 'status-message text-green-600 text-lg success-message', true, 3000);
    }
}

// 清除错误标记
function clearErrors() {
    document.querySelectorAll('[data-row][data-col]').forEach(cell => {
        cell.classList.remove('bg-red-200');
    });
    // 清除状态消息
    updateStatusMessage('', '');
}

// 清空棋盘
function clearBoard() {
    sudokuBoard = Array(9).fill().map(() => Array(9).fill(0));
    originalBoard = Array(9).fill().map(() => Array(9).fill(0));
    updateBoardDisplay();
    statusMessage.textContent = '';
    // 隐藏提示信息区域
    const hintArea = document.getElementById('hintArea');
    if (hintArea) hintArea.classList.add('hidden');
    difficultyDisplay.textContent = '难度: 未知';
    stepControls.classList.add('hidden');
    clearErrors();
    
    // 隐藏数独区域
    const sudokuSection = document.getElementById('sudokuSection');
    if (sudokuSection) {
        sudokuSection.classList.add('hidden');
    }
    
    // 显示模式选择区域
    const modeSelection = document.querySelector('.flex.flex-col.md\\:flex-row.justify-center.gap-6');
    if (modeSelection) {
        modeSelection.classList.remove('hidden');
    }
    
    // 移除模式按钮激活状态
    const manualModeBtn = document.getElementById('manualModeBtn');
    const imageModeBtn = document.getElementById('imageModeBtn');
    if (manualModeBtn) manualModeBtn.classList.remove('active');
    if (imageModeBtn) imageModeBtn.classList.remove('active');
    
    // 隐藏返回首页按钮
    const backToHomeBtn = document.getElementById('backToHomeBtn');
    if (backToHomeBtn) {
        backToHomeBtn.classList.add('hidden');
    }
    
    // 隐藏图片预览容器
    const imagePreviewContainer = document.getElementById('imagePreviewContainer');
    if (imagePreviewContainer) {
        imagePreviewContainer.classList.add('hidden');
    }
    
    // 隐藏图片上传区域
    const imageUploadSection = document.getElementById('imageUploadSection');
    if (imageUploadSection) {
        imageUploadSection.classList.add('hidden');
    }
    
    // 显示上传区域
    const uploadArea = document.getElementById('uploadArea');
    if (uploadArea) {
        uploadArea.classList.remove('hidden');
    }
    
    // 隐藏图片预览在网格旁边
    const imagePreviewWrapper = document.getElementById('imagePreviewWrapper');
    if (imagePreviewWrapper) {
        imagePreviewWrapper.style.display = 'none';
    }
    if (previewImage) {
        previewImage.style.display = 'none';
    }
    
    // 重置文件输入以便可以再次选择相同文件
    if (fileUpload) {
        fileUpload.value = '';
    }
}

// 处理图片上传
function handleImageUpload(event) {
    const file = event.target.files[0];
    if (!file) return;
    
    // 显示上传状态
    updateStatusMessage('<i class="fas fa-circle-notch fa-spin mr-2"></i>正在识别图片中的数独...', 'status-message text-blue-600 info-message');
    
    const reader = new FileReader();
    reader.onload = function(e) {
        previewImage.src = e.target.result;
        // 显示网格旁边的预览图片
        const imagePreviewWrapper = document.getElementById('imagePreviewWrapper');
        if (imagePreviewWrapper && previewImage) {
            previewImage.style.display = 'block';
            imagePreviewWrapper.style.display = 'flex';
        }
        // 隐藏上传区域的预览容器
        if (imagePreviewContainer) {
            imagePreviewContainer.classList.add('hidden');
        }
        // 隐藏上传区域
        uploadArea.classList.add('hidden');
        // 显示操作按钮
        operationButtons.classList.remove('hidden');
        
        // 获取当前选择的OCR引擎
        const ocrEngine = appConfig.ocrEngine || 'tesseract';
        
        if (ocrEngine === 'baidu') {
            // 使用百度OCR
            ocrWithBaidu(e.target.result);
        } else {
            // 使用Tesseract.js(基本版本)
            ocrWithTesseract(e.target.result);
        }
    };
    reader.readAsDataURL(file);
}

// 使用Tesseract.js进行OCR识别
function ocrWithTesseract(imageData) {
    // 保存当前棋盘状态, 以便在OCR失败时恢复
    const previousBoard = JSON.parse(JSON.stringify(sudokuBoard));
    
    // 清空当前棋盘
    sudokuBoard = Array(9).fill().map(() => Array(9).fill(0));
    originalBoard = Array(9).fill().map(() => Array(9).fill(0));
    updateBoardDisplay();
    
    updateStatusMessage('<i class="fas fa-circle-notch fa-spin mr-2"></i>正在使用Tesseract.js识别图片中的数独...', 'status-message text-blue-600 info-message');
    
    Tesseract.recognize(
        imageData,
        'eng',
        { 
            logger: info => console.log(info),
            tessedit_char_whitelist: '123456789',
            preserve_interword_spaces: '1',
            page_separator: '',
            tessedit_pageseg_mode: Tesseract.PSM.SINGLE_BLOCK
        }
    ).then(({ data: { text, words } }) => {
        console.log('识别到的完整文本:', text);
        console.log('识别到的单词:', words);
        updateStatusMessage('<i class="fas fa-circle-notch fa-spin mr-2"></i>识别完成，正在解析数独...');
        // 解析识别到的文本并填充到数独棋盘
        parseSudokuFromTextWithPosition({ data: { words, text } }, imageData);
    }).catch(err => {
        console.error(err);
        // 提供更详细的错误信息
        let errorMessage = '识别失败';
        if (err.message) {
            errorMessage += ': ' + err.message;
        }
        updateStatusMessage('<i class="fas fa-exclamation-circle mr-2"></i>' + errorMessage + '，请重试', 'status-message text-red-600 error-message');
        
        // 恢复之前的棋盘状态
        sudokuBoard = previousBoard;
        updateBoardDisplay();
    });
}

// 使用百度OCR进行识别
function ocrWithBaidu(imageData) {
    // 保存当前棋盘状态, 以便在OCR失败时恢复
    const previousBoard = JSON.parse(JSON.stringify(sudokuBoard));
    
    // 清空当前棋盘
    sudokuBoard = Array(9).fill().map(() => Array(9).fill(0));
    originalBoard = Array(9).fill().map(() => Array(9).fill(0));
    updateBoardDisplay();
    
    updateStatusMessage('<i class="fas fa-circle-notch fa-spin mr-2"></i>正在使用百度OCR识别图片中的数独...', 'status-message text-blue-600 info-message');
    
    // 获取百度OCR密钥
    const apiKey = appConfig.baiduOcr.apiKey;
    const secretKey = appConfig.baiduOcr.secretKey;
    
    console.log('使用百度OCR，API Key:', apiKey ? '已配置' : '未配置', 'Secret Key:', secretKey ? '已配置' : '未配置');
    
    if (!apiKey || !secretKey) {
        updateStatusMessage('<i class="fas fa-exclamation-circle mr-2"></i>请先在设置中配置百度OCR的API Key和Secret Key', 'status-message text-red-600 error-message');
        showFriendlyAlert('请先在设置中配置百度OCR的API Key和Secret Key。\n\n配置步骤：\n1. 访问百度AI开放平台创建应用\n2. 获取API Key和Secret Key\n3. 在设置页面中配置密钥\n4. 选择百度OCR作为默认引擎');
        return;
    }
    
    // 预处理图像以提高OCR准确性
    const img = new Image();
    img.onload = function() {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage(img, 0, 0);
        
        let imageDataObj = ctx.getImageData(0, 0, canvas.width, canvas.height);
        
        // 应用针对数独优化的图像预处理（更强版本）
        imageDataObj = preprocessSudokuImageForBaiduOCROptimizedV2(imageDataObj);
        
        // 将处理后的图像数据转换为base64
        ctx.putImageData(imageDataObj, 0, 0);
        const processedImageData = canvas.toDataURL('image/png');
        
        // 获取访问令牌
        getBaiduAccessToken(apiKey, secretKey)
            .then(accessToken => {
                console.log('成功获取访问令牌');
                updateStatusMessage('<i class="fas fa-circle-notch fa-spin mr-2"></i>已获取访问令牌，正在识别数独...');
                // 调用百度OCR API
                return callBaiduOcrApi(processedImageData, accessToken);
            })
            .then(result => {
                console.log('百度OCR识别完成');
                updateStatusMessage('<i class="fas fa-circle-notch fa-spin mr-2"></i>识别完成，正在解析数独...');
                // 解析识别结果
                parseBaiduOcrResult(result);
            })
            .catch(err => {
                console.error('百度OCR识别失败:', err);
                let errorMessage = '百度OCR识别失败';
                if (err.message) {
                    errorMessage += ': ' + err.message;
                }
                updateStatusMessage('<i class="fas fa-exclamation-circle mr-2"></i>' + errorMessage);
                statusMessage.className = 'status-message text-red-600 error-message';
                
                // 恢复之前的棋盘状态
                sudokuBoard = previousBoard;
                updateBoardDisplay();
                
                // 根据错误类型提供更具体的提示
                if (err.message && (err.message.includes('网络连接失败') || err.message.includes('fetch') || err.message.includes('CORS'))) {
                    showFriendlyAlert('百度OCR识别失败，可能是由于浏览器的跨域限制。\n\n解决方案：\n1. 安装CORS解除阻止浏览器扩展\n2. 使用Tesseract.js OCR引擎（无跨域问题）\n3. 配置本地服务器代理（如server.js）');
                } else if (err.message && err.message.includes('API Key')) {
                    showFriendlyAlert('API密钥配置错误，请检查在设置页面中配置的百度OCR密钥是否正确。');
                } else if (err.message && err.message.includes('invalid client')) {
                    showFriendlyAlert('API密钥无效，请检查在设置页面中配置的百度OCR密钥是否正确。');
                } else {
                    showFriendlyAlert(`百度OCR识别失败: ${err.message}\n\n建议使用Tesseract.js OCR引擎以避免跨域问题`);
                }
            });
    };
    
    img.src = imageData;
}

// 获取百度OCR访问令牌
function getBaiduAccessToken(apiKey, secretKey) {
    return new Promise((resolve, reject) => {
        // 检查API密钥是否为空
        if (!apiKey || !secretKey) {
            reject(new Error('API Key或Secret Key不能为空'));
            return;
        }
        
        // 使用PHP后端而不是直接调用百度API
        fetch('baidu_ocr.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                action: 'get_token',
                apiKey: apiKey,
                secretKey: secretKey
            })
        })
        .then(response => {
            // 检查响应状态
            if (response.status === 500) {
                // 更详细的500错误诊断
                throw new Error('服务器内部错误 (500): 请检查以下可能原因:\n1. PHP环境未安装或未正确配置\n2. PHP文件权限问题\n3. 服务器配置错误\n4. 网络连接问题');
            }
            
            if (!response.ok) {
                throw new Error(`网络错误: ${response.status} ${response.statusText}`);
            }
            return response.json();
        })
        .then(data => {
            // 检查响应数据
            if (!data) {
                throw new Error('服务器返回空响应');
            }
            
            if (!data.success) {
                throw new Error(data.error || '获取访问令牌失败');
            }
            
            const tokenData = data.data;
            console.log('获取访问令牌返回数据:', tokenData);
            
            if (tokenData.access_token) {
                // 检查令牌是否即将过期，百度OCR的access_token有效期为30天
                const expiresIn = tokenData.expires_in || 2592000; // 默认30天
                const now = new Date().getTime();
                const expirationTime = now + (expiresIn * 1000);
                
                // 将令牌和过期时间保存到localStorage
                localStorage.setItem('baiduOcrToken', JSON.stringify({
                    accessToken: tokenData.access_token,
                    expirationTime: expirationTime
                }));
                
                resolve(tokenData.access_token);
            } else {
                reject(new Error('获取访问令牌失败: 未返回access_token'));
            }
        })
        .catch(err => {
            console.error('获取访问令牌错误:', err);
            // 检查是否有缓存的令牌可以使用
            const cachedToken = localStorage.getItem('baiduOcrToken');
            if (cachedToken) {
                const tokenData = JSON.parse(cachedToken);
                const now = new Date().getTime();
                // 如果缓存的令牌还未过期，使用缓存的令牌
                if (tokenData.expirationTime > now) {
                    console.log('使用缓存的访问令牌');
                    resolve(tokenData.accessToken);
                    return;
                }
            }
            
            reject(new Error(`获取访问令牌失败: ${err.message}`));
        });
    });
}

// 调用百度OCR API
function callBaiduOcrApi(imageData, accessToken) {
    return new Promise((resolve, reject) => {
        // 直接使用完整的base64数据，不需要分割
        const base64Data = imageData.split(',')[1];
        
        // 使用PHP后端而不是直接调用百度API
        fetch('baidu_ocr.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                action: 'recognize',
                imageData: base64Data,
                apiKey: appConfig.baiduOcr.apiKey,
                secretKey: appConfig.baiduOcr.secretKey
            })
        })
        .then(response => {
            // 检查响应状态
            if (response.status === 500) {
                return response.text().then(text => {
                    throw new Error('服务器内部错误: ' + text);
                });
            }
            
            if (!response.ok) {
                // 尝试读取错误响应体
                return response.text().then(text => {
                    throw new Error(`网络错误: ${response.status} ${response.statusText} - ${text}`);
                });
            }
            return response.json();
        })
        .then(data => {
            // 检查响应数据
            if (!data) {
                throw new Error('服务器返回空响应');
            }
            
            if (!data.success) {
                throw new Error(data.error || 'OCR识别失败');
            }
            
            console.log('百度OCR API返回数据:', data.data);
            resolve(data.data);
        })
        .catch(err => {
            console.error('百度OCR API调用错误:', err);
            reject(new Error(`OCR识别失败: ${err.message}`));
        });
    });
}

// 解析百度OCR结果
function parseBaiduOcrResult(result) {
    console.log('百度OCR返回结果:', result);
    
    // 添加详细的调试信息
    console.log('百度OCR详细结果:');
    console.log('- 错误码:', result.error_code);
    console.log('- 错误信息:', result.error_msg);
    console.log('- 结果数量:', result.words_result_num);
    console.log('- 结果详情:', result.words_result);
    
    // 检查是否有错误
    if (result.error_code) {
        updateStatusMessage(`<i class="fas fa-exclamation-circle mr-2"></i>百度OCR识别失败: ${result.error_msg || '未知错误'}`);
        statusMessage.className = 'status-message text-red-600 error-message';
        return;
    }
    
    // 初始化空白数独棋盘
    const sudoku = Array(9).fill().map(() => Array(9).fill(0));
    let recognizedDigits = 0;
    
    try {
        // 检查是否有有效的OCR结果
        if (result && result.words_result) {
            // 创建一个9x9的网格来存储识别到的数字
            const grid = Array(9).fill().map(() => Array(9).fill(null));
            const confidence = Array(9).fill().map(() => Array(9).fill(0)); // 用于存储置信度
            
            // 添加调试信息
            console.log(`共识别到 ${result.words_result_num} 个结果`);
            
            // 遍历识别到的单词
            result.words_result.forEach((wordObj, index) => {
                // 获取单词的文本和位置信息
                let text = wordObj.words || '';
                const location = wordObj.location || {};
                const probability = wordObj.probability || {}; // 获取概率信息
                
                // 添加详细的调试信息
                console.log(`识别结果 ${index}:`);
                console.log('  - 文本:', text);
                console.log('  - 位置:', location);
                console.log('  - 概率:', probability);
                
                // 处理字符级别的识别结果（chars字段）
                if (wordObj.chars && Array.isArray(wordObj.chars)) {
                    console.log(`  - 字符级别结果，共 ${wordObj.chars.length} 个字符`);
                    wordObj.chars.forEach((charObj, charIndex) => {
                        const charText = charObj.char || '';
                        const charLocation = charObj.location || {};
                        const charProbability = charObj.probability || {};
                        
                        console.log(`    - 字符 ${charIndex}: "${charText}"`);
                        console.log('      位置:', charLocation);
                        console.log('      概率:', charProbability);
                        
                        // 检查字符是否为单个数字
                        if (/^[1-9]$/.test(charText) && charLocation.left !== undefined && charLocation.top !== undefined) {
                            const digit = parseInt(charText);
                            // 获取置信度，如果没有则默认为0.9
                            const prob = charProbability.average || 0.9;
                            
                            // 只处理置信度较高的识别结果
                            if (prob < 0.7) {
                                console.log(`      跳过低置信度识别结果: ${digit} (置信度: ${prob})`);
                                return;
                            }
                            
                            // 计算字符的中心点
                            const centerX = charLocation.left + (charLocation.width || 0) / 2;
                            const centerY = charLocation.top + (charLocation.height || 0) / 2;
                            
                            // 根据图像尺寸动态计算网格位置
                            const img = document.getElementById('previewImage');
                            if (img) {
                                const handleImageLoad = function() {
                                    const imageWidth = img.naturalWidth || img.width;
                                    const imageHeight = img.naturalHeight || img.height;
                                    
                                    // 计算每个单元格的尺寸
                                    const cellWidth = imageWidth / 9;
                                    const cellHeight = imageHeight / 9;
                                    
                                    // 根据中心点位置确定数字在数独网格中的位置
                                    const col = Math.min(8, Math.max(0, Math.floor(centerX / cellWidth)));
                                    const row = Math.min(8, Math.max(0, Math.floor(centerY / cellHeight)));
                                    
                                    console.log(`      数字 ${digit} 位于 (${centerX}, ${centerY}) -> 网格位置 [${row}][${col}]`, `置信度: ${prob}`);
                                    
                                    // 存储数字到网格中（如果有冲突，保留置信度更高的）
                                    if (grid[row][col] === null || confidence[row][col] < prob) {
                                        const oldValue = grid[row][col];
                                        grid[row][col] = digit;
                                        confidence[row][col] = prob;
                                        // 只有当数字被更新时才增加计数
                                        if (oldValue !== digit) {
                                            recognizedDigits++;
                                        }
                                    }
                                };
                                
                                // 如果图片已经加载完成，直接触发处理
                                if (img.complete) {
                                    handleImageLoad();
                                } else {
                                    img.addEventListener('load', handleImageLoad);
                                }
                            }
                        } else {
                            console.log(`      跳过无效字符识别结果 ${charIndex}: "${charText}"`);
                        }
                    });
                } else {
                    // 处理单词级别的识别结果
                    // 移除干扰字符（如竖线、空格等）
                    text = text.replace(/[|\s\-_]/g, '');
                    
                    // 检查文本是否为单个数字
                    if (/^[1-9]$/.test(text) && location.left !== undefined && location.top !== undefined) {
                        const digit = parseInt(text);
                        // 获取置信度，如果没有则默认为0.9
                        const prob = probability.average || 0.9;
                        
                        // 只处理置信度较高的识别结果
                        if (prob < 0.7) {
                            console.log(`跳过低置信度识别结果: ${digit} (置信度: ${prob})`);
                            return;
                        }
                        
                        // 计算单词的中心点
                        const centerX = location.left + (location.width || 0) / 2;
                        const centerY = location.top + (location.height || 0) / 2;
                        
                        // 根据图像尺寸动态计算网格位置
                        const img = document.getElementById('previewImage');
                        if (img) {
                            const handleImageLoad = function() {
                                const imageWidth = img.naturalWidth || img.width;
                                const imageHeight = img.naturalHeight || img.height;
                                
                                // 计算每个单元格的尺寸
                                const cellWidth = imageWidth / 9;
                                const cellHeight = imageHeight / 9;
                                
                                // 根据中心点位置确定数字在数独网格中的位置
                                const col = Math.min(8, Math.max(0, Math.floor(centerX / cellWidth)));
                                const row = Math.min(8, Math.max(0, Math.floor(centerY / cellHeight)));
                                
                                console.log(`数字 ${digit} 位于 (${centerX}, ${centerY}) -> 网格位置 [${row}][${col}]`, `置信度: ${prob}`);
                                
                                // 存储数字到网格中（如果有冲突，保留置信度更高的）
                                if (grid[row][col] === null || confidence[row][col] < prob) {
                                    const oldValue = grid[row][col];
                                    grid[row][col] = digit;
                                    confidence[row][col] = prob;
                                    // 只有当数字被更新时才增加计数
                                    if (oldValue !== digit) {
                                        recognizedDigits++;
                                    }
                                }
                            };
                            
                            // 如果图片已经加载完成，直接触发处理
                            if (img.complete) {
                                handleImageLoad();
                            } else {
                                img.addEventListener('load', handleImageLoad);
                            }
                        }
                    } else {
                        console.log(`跳过无效识别结果 ${index}: "${text}"`);
                    }
                }
            });
            
            // 等待所有图像加载完成后再处理结果
            setTimeout(() => {
                // 将网格中的数字填充到数独棋盘
                for (let i = 0; i < 9; i++) {
                    for (let j = 0; j < 9; j++) {
                        if (grid[i][j] !== null) {
                            sudoku[i][j] = grid[i][j];
                        }
                    }
                }
                
                // 检查识别到的数字数量
                if (recognizedDigits < 17) {
                    statusMessage.innerHTML = `<i class="fas fa-exclamation-circle mr-2"></i>识别到的数字不足: 只有${recognizedDigits}个数字，使用示例数独`;
                    statusMessage.className = 'status-message text-yellow-600 info-message';
                    
                    const sampleSudoku = [
                        [5, 3, 0, 0, 7, 0, 0, 0, 0],
                        [6, 0, 0, 1, 9, 5, 0, 0, 0],
                        [0, 9, 8, 0, 0, 0, 0, 6, 0],
                        [8, 0, 0, 0, 6, 0, 0, 0, 3],
                        [4, 0, 0, 8, 0, 3, 0, 0, 1],
                        [7, 0, 0, 0, 2, 0, 0, 0, 6],
                        [0, 6, 0, 0, 0, 0, 2, 8, 0],
                        [0, 0, 0, 4, 1, 9, 0, 0, 5],
                        [0, 0, 0, 0, 8, 0, 0, 7, 9]
                    ];
                    
                    for (let i = 0; i < 9; i++) {
                        for (let j = 0; j < 9; j++) {
                            sudokuBoard[i][j] = sampleSudoku[i][j];
                            originalBoard[i][j] = sampleSudoku[i][j];
                        }
                    }
                } else {
                    // 将识别到的数独填充到棋盘
                    for (let i = 0; i < 9; i++) {
                        for (let j = 0; j < 9; j++) {
                            sudokuBoard[i][j] = sudoku[i][j];
                            originalBoard[i][j] = sudoku[i][j];
                        }
                    }
                    
                    statusMessage.innerHTML = `<i class="fas fa-check-circle mr-2"></i>数独识别完成！识别到${recognizedDigits}个数字，已填入`;
                    statusMessage.className = 'status-message text-green-600 success-message';
                }
                
                // 更新显示
                updateBoardDisplay();
                updateDifficulty();
                
                // 显示数独网格
                sudokuGridContainer.classList.remove('hidden');
                
                // 自动执行错误检查
                setTimeout(checkErrors, 500);
            }, 500);
        } else {
            console.log('百度OCR未返回有效结果');
            statusMessage.innerHTML = '<i class="fas fa-exclamation-circle mr-2"></i>百度OCR未返回有效结果';
            statusMessage.className = 'status-message text-red-600 error-message';
        }
    } catch (error) {
        console.error('解析百度OCR结果时出错:', error);
        statusMessage.innerHTML = '<i class="fas fa-exclamation-circle mr-2"></i>解析OCR结果时出错，请重试';
        statusMessage.className = 'status-message text-red-600 error-message';
    }
}

// 从文本解析数独(带位置信息)
function parseSudokuFromTextWithPosition(result, imageData) {
    // 初始化空白数独棋盘
    const sudoku = Array(9).fill().map(() => Array(9).fill(0));
    let recognizedDigits = 0;
    
    try {
        // 检查是否有有效的OCR结果
        if (result && result.data && result.data.words) {
            // 创建一个9x9的网格来存储识别到的数字
            const grid = Array(9).fill().map(() => Array(9).fill(null));
            const confidence = Array(9).fill().map(() => Array(9).fill(0)); // 用于存储置信度
            
            // 获取文本内容用于回退
            const text = result.data.text || "";
            
            // 创建一个图像元素来获取图像尺寸
            const img = new Image();
            img.src = imageData;
            
            img.onload = function() {
                const imageWidth = img.naturalWidth || img.width;
                const imageHeight = img.naturalHeight || img.height;
                
                // 计算每个单元格的尺寸
                const cellWidth = imageWidth / 9;
                const cellHeight = imageHeight / 9;
                
                console.log(`图像尺寸: ${imageWidth}x${imageHeight}, 单元格尺寸: ${cellWidth}x${cellHeight}`);
                
                // 遍历识别到的单词
                result.data.words.forEach((word, index) => {
                    // 获取单词的文本和位置信息
                    let text = word.text || '';
                    const bbox = word.bbox || {};
                    const conf = word.confidence || 0;
                    
                    // 移除干扰字符（如竖线）
                    text = text.replace(/[|]/g, '');
                    
                    console.log(`单词 ${index}: "${text}", 位置:`, bbox, `置信度: ${conf}`);
                    
                    // 检查文本是否为单个数字
                    if (/^[1-9]$/.test(text) && bbox.x0 !== undefined && bbox.y0 !== undefined) {
                        const digit = parseInt(text);
                        
                        // 计算单词的中心点
                        const centerX = (bbox.x0 + bbox.x1) / 2;
                        const centerY = (bbox.y0 + bbox.y1) / 2;
                        
                        // 根据中心点位置确定数字在数独网格中的位置
                        const col = Math.min(8, Math.max(0, Math.floor(centerX / cellWidth)));
                        const row = Math.min(8, Math.max(0, Math.floor(centerY / cellHeight)));
                        
                        console.log(`数字 ${digit} 位于 (${centerX}, ${centerY}) -> 网格位置 [${row}][${col}]`);
                        
                        // 存储数字到网格中（如果有冲突，保留置信度更高的）
                        if (grid[row][col] === null || confidence[row][col] < conf) {
                            grid[row][col] = digit;
                            confidence[row][col] = conf;
                        }
                    } else if (/^[1-9]{2,}$/.test(text) && bbox.x0 !== undefined && bbox.y0 !== undefined) {
                        // 如果是多个数字连在一起，尝试拆分它们
                        const digits = text.split('');
                        const wordWidth = bbox.x1 - bbox.x0;
                        const digitWidth = wordWidth / digits.length;
                        
                        for (let i = 0; i < digits.length; i++) {
                            if (/^[1-9]$/.test(digits[i])) {
                                const digit = parseInt(digits[i]);
                                // 计算每个数字的中心点
                                const digitCenterX = bbox.x0 + (i + 0.5) * digitWidth;
                                const digitCenterY = (bbox.y0 + bbox.y1) / 2;
                                
                                // 根据中心点位置确定数字在数独网格中的位置
                                const col = Math.min(8, Math.max(0, Math.floor(digitCenterX / cellWidth)));
                                const row = Math.min(8, Math.max(0, Math.floor(digitCenterY / cellHeight)));
                                
                                console.log(`拆分数字 ${digit} 位于 (${digitCenterX}, ${digitCenterY}) -> 网格位置 [${row}][${col}]`);
                                
                                // 存储数字到网格中（如果有冲突，保留置信度更高的）
                                if (grid[row][col] === null || confidence[row][col] < conf) {
                                    grid[row][col] = digit;
                                    confidence[row][col] = conf;
                                }
                            }
                        }
                    } else if (/^1$/.test(text) && bbox.x0 !== undefined && bbox.y0 !== undefined) {
                        // 特殊处理：如果识别到单独的"1"且置信度较低，可能是网格线误识别
                        const conf = word.confidence || 0;
                        if (conf < 50) { // 置信度阈值，可根据实际情况调整
                            console.log(`忽略低置信度的数字1 (置信度: ${conf})，可能是网格线误识别`);
                            return; // 跳过这个识别结果
                        }
                        
                        const digit = parseInt(text);
                        
                        // 计算单词的中心点
                        const centerX = (bbox.x0 + bbox.x1) / 2;
                        const centerY = (bbox.y0 + bbox.y1) / 2;
                        
                        // 根据中心点位置确定数字在数独网格中的位置
                        const col = Math.min(8, Math.max(0, Math.floor(centerX / cellWidth)));
                        const row = Math.min(8, Math.max(0, Math.floor(centerY / cellHeight)));
                        
                        console.log(`数字 ${digit} 位于 (${centerX}, ${centerY}) -> 网格位置 [${row}][${col}]`);
                        
                        // 存储数字到网格中（如果有冲突，保留置信度更高的）
                        if (grid[row][col] === null || confidence[row][col] < conf) {
                            grid[row][col] = digit;
                            confidence[row][col] = conf;
                        }
                    }
                });
                
                // 计算识别到的数字数量
                for (let i = 0; i < 9; i++) {
                    for (let j = 0; j < 9; j++) {
                        if (grid[i][j] !== null) {
                            recognizedDigits++;
                        }
                    }
                }
                
                // 将网格中的数字填充到数独棋盘
                for (let i = 0; i < 9; i++) {
                    for (let j = 0; j < 9; j++) {
                        if (grid[i][j] !== null) {
                            sudoku[i][j] = grid[i][j];
                        }
                    }
                }
                
                // 更新棋盘显示
                finishParsing(sudoku, recognizedDigits, text);
            };
            
            // 如果图像已经加载完成
            if (img.complete && img.naturalWidth !== 0) {
                img.onload();
            } else if (img.complete) {
                // 回退到文本解析
                console.log("图像加载失败，回退到文本解析");
                const result = tryParseSudokuFromText(text);
                const sudoku = result.sudoku;
                const recognizedDigits = result.recognizedDigits;
                finishParsing(sudoku, recognizedDigits, text);
            }
        } else {
            // 如果没有位置信息，回退到文本解析
            console.log("没有位置信息，回退到文本解析");
            const text = result && result.data ? (result.data.text || "") : "";
            const resultObj = tryParseSudokuFromText(text);
            const sudoku = resultObj.sudoku;
            const recognizedDigits = resultObj.recognizedDigits;
            finishParsing(sudoku, recognizedDigits, text);
        }
    } catch (error) {
        console.error('解析Tesseract结果时出错:', error);
        recognizedDigits = 0;
        // 出错时回退到文本解析
        const text = result && result.data ? (result.data.text || "") : "";
        const resultObj = tryParseSudokuFromText(text);
        const sudoku = resultObj.sudoku;
        const recognizedDigits = resultObj.recognizedDigits;
        finishParsing(sudoku, recognizedDigits, text);
    }
    
    // 完成解析的通用函数
    function finishParsing(sudoku, recognizedDigits, originalText) {
        // 显示数独网格
        sudokuGridContainer.classList.remove('hidden');
        // 检查识别到的数字数量
        if (recognizedDigits < 17) {
            statusMessage.innerHTML = `<i class="fas fa-exclamation-circle mr-2"></i>识别到的数字不足: 只有${recognizedDigits}个数字，使用示例数独`;
            statusMessage.className = 'status-message text-yellow-600 info-message';
            
            const sampleSudoku = [
                [5, 3, 0, 0, 7, 0, 0, 0, 0],
                [6, 0, 0, 1, 9, 5, 0, 0, 0],
                [0, 9, 8, 0, 0, 0, 0, 6, 0],
                [8, 0, 0, 0, 6, 0, 0, 0, 3],
                [4, 0, 0, 8, 0, 3, 0, 0, 1],
                [7, 0, 0, 0, 2, 0, 0, 0, 6],
                [0, 6, 0, 0, 0, 0, 2, 8, 0],
                [0, 0, 0, 4, 1, 9, 0, 0, 5],
                [0, 0, 0, 0, 8, 0, 0, 7, 9]
            ];
            
            for (let i = 0; i < 9; i++) {
                for (let j = 0; j < 9; j++) {
                    sudokuBoard[i][j] = sampleSudoku[i][j];
                    originalBoard[i][j] = sampleSudoku[i][j];
                }
            }
        } else {
            // 将识别到的数独填充到棋盘
            for (let i = 0; i < 9; i++) {
                for (let j = 0; j < 9; j++) {
                    sudokuBoard[i][j] = sudoku[i][j];
                    originalBoard[i][j] = sudoku[i][j];
                }
            }
            
            // 显示提示信息：识别完成但需要手动点击求解
            statusMessage.innerHTML = `<i class="fas fa-check-circle mr-2"></i>数独识别完成！识别到${recognizedDigits}个数字，已填入，请检查确认无误后，点击求解按钮`;
            statusMessage.className = 'status-message text-green-600 success-message';
        }
        
        // 更新显示
        updateBoardDisplay();
        updateDifficulty();
        
        // 自动执行错误检查
        checkErrors();
    }
}

// 尝试解析数独文本（即使OCR不完美）
function tryParseSudokuFromText(text) {
    console.log('原始OCR文本:', text);
    
    // 首先清理文本，移除干扰字符（如竖线、空格等）
    let cleanedText = '';
    const lines = text.split('\n');
    
    // 遍历每一行，提取数字
    for (let i = 0; i < lines.length; i++) {
        const line = lines[i];
        console.log(`处理第${i}行: "${line}"`);
        
        // 移除竖线和其他干扰字符，只保留数字
        const cleanedLine = line.replace(/[|]/g, ' ');
        console.log(`清理后第${i}行: "${cleanedLine}"`);
        
        // 将行中的数字提取出来
        const digits = cleanedLine.match(/[1-9]/g) || [];
        console.log(`第${i}行提取到的数字:`, digits);
        
        // 将数字添加到cleanedText中
        cleanedText += digits.join('');
    }
    
    console.log('清理后的文本:', cleanedText);
    
    // 检查是否有足够的数字
    let recognizedDigits = cleanedText.length;
    if (cleanedText.length < 17) {
        statusMessage.innerHTML = `<i class="fas fa-exclamation-circle mr-2"></i>识别到的数字不足: 只有${cleanedText.length}个数字，使用示例数独`;
        statusMessage.className = 'status-message text-yellow-600 info-message';
        cleanedText = "530070000600195000098000060800060003400803001700020006060000280000419005000080079";
    } else {
        // 只取前81个数字
        cleanedText = cleanedText.substring(0, 81);
        statusMessage.innerHTML = '<i class="fas fa-circle-notch fa-spin mr-2"></i>数独识别完成！';
        statusMessage.className = 'status-message text-green-600 success-message';
    }
    
    // 创建数独数组
    const sudoku = Array(9).fill().map(() => Array(9).fill(0));
    
    // 填充数独棋盘
    for (let i = 0; i < 9; i++) {
        for (let j = 0; j < 9; j++) {
            const digit = parseInt(cleanedText[i * 9 + j]);
            sudoku[i][j] = isNaN(digit) ? 0 : digit;
        }
    }
    
    // 更新显示
    updateBoardDisplay();
    updateDifficulty();
    
    // 返回解析结果
    return { sudoku, recognizedDigits };
}

// 从文本解析数独
function parseSudokuFromText(text) {
    const result = tryParseSudokuFromText(text);
    const sudoku = result.sudoku;
    const recognizedDigits = result.recognizedDigits;
    
    // 检查识别到的数字数量
    if (recognizedDigits < 17) {
        statusMessage.innerHTML = `<i class="fas fa-exclamation-circle mr-2"></i>识别到的数字不足: 只有${recognizedDigits}个数字，使用示例数独`;
        statusMessage.className = 'status-message text-yellow-600 info-message';
        
        const sampleSudoku = [
            [5, 3, 0, 0, 7, 0, 0, 0, 0],
            [6, 0, 0, 1, 9, 5, 0, 0, 0],
            [0, 9, 8, 0, 0, 0, 0, 6, 0],
            [8, 0, 0, 0, 6, 0, 0, 0, 3],
            [4, 0, 0, 8, 0, 3, 0, 0, 1],
            [7, 0, 0, 0, 2, 0, 0, 0, 6],
            [0, 6, 0, 0, 0, 0, 2, 8, 0],
            [0, 0, 0, 4, 1, 9, 0, 0, 5],
            [0, 0, 0, 0, 8, 0, 0, 7, 9]
        ];
        
        for (let i = 0; i < 9; i++) {
            for (let j = 0; j < 9; j++) {
                sudokuBoard[i][j] = sampleSudoku[i][j];
                originalBoard[i][j] = sampleSudoku[i][j];
            }
        }
    } else {
        // 将识别到的数独填充到棋盘
        for (let i = 0; i < 9; i++) {
            for (let j = 0; j < 9; j++) {
                sudokuBoard[i][j] = sudoku[i][j];
                originalBoard[i][j] = sudoku[i][j];
            }
        }
        
        // 显示提示信息：识别完成但需要手动点击求解
        statusMessage.innerHTML = `<i class="fas fa-check-circle mr-2"></i>数独识别完成！识别到${recognizedDigits}个数字，已填入，请检查确认无误后，点击求解按钮`;
        statusMessage.className = 'status-message text-green-600 success-message';
    }
    
    // 更新显示
    updateBoardDisplay();
    updateDifficulty();
    
    // 隐藏上传状态
    uploadStatus.classList.add('hidden');
}

// 评估数独难度
function evaluateDifficulty(board) {
    let emptyCells = 0;
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            if (board[row][col] === 0) {
                emptyCells++;
            }
        }
    }
    
    // 计算已填数字数量
    const filledCells = 81 - emptyCells;
    
    if (emptyCells < 30) return `简单（九宫${filledCells}数）`;
    if (emptyCells < 45) return `中等（九宫${filledCells}数）`;
    if (emptyCells < 60) return `困难（九宫${filledCells}数）`;
    return `极难（九宫${filledCells}数）`;
}

// 检查数独是否有效
function isValidSudoku(board) {
    // 检查行
    for (let row = 0; row < 9; row++) {
        const seen = new Set();
        for (let col = 0; col < 9; col++) {
            const num = board[row][col];
            if (num !== 0) {
                if (seen.has(num)) {
                    return false;
                }
                seen.add(num);
            }
        }
    }
    
    // 检查列
    for (let col = 0; col < 9; col++) {
        const seen = new Set();
        for (let row = 0; row < 9; row++) {
            const num = board[row][col];
            if (num !== 0) {
                if (seen.has(num)) {
                    return false;
                }
                seen.add(num);
            }
        }
    }
    
    // 检查3x3子网格
    for (let boxRow = 0; boxRow < 3; boxRow++) {
        for (let boxCol = 0; boxCol < 3; boxCol++) {
            const seen = new Set();
            for (let row = boxRow * 3; row < boxRow * 3 + 3; row++) {
                for (let col = boxCol * 3; col < boxCol * 3 + 3; col++) {
                    const num = board[row][col];
                    if (num !== 0) {
                        if (seen.has(num)) {
                            return false;
                        }
                        seen.add(num);
                    }
                }
            }
        }
    }
    
    return true;
}

// 查找数独错误
function findSudokuErrors(board) {
    const errors = [];
    
    // 检查行
    for (let row = 0; row < 9; row++) {
        const seen = {};
        for (let col = 0; col < 9; col++) {
            const num = board[row][col];
            if (num !== 0) {
                if (seen[num]) {
                    errors.push({ row: row, col: col });
                    errors.push({ row: row, col: seen[num] });
                } else {
                    seen[num] = col;
                }
            }
        }
    }
    
    // 检查列
    for (let col = 0; col < 9; col++) {
        const seen = {};
        for (let row = 0; row < 9; row++) {
            const num = board[row][col];
            if (num !== 0) {
                if (seen[num]) {
                    errors.push({ row: row, col: col });
                    errors.push({ row: seen[num], col: col });
                } else {
                    seen[num] = row;
                }
            }
        }
    }
    
    // 检查3x3子网格
    for (let boxRow = 0; boxRow < 3; boxRow++) {
        for (let boxCol = 0; boxCol < 3; boxCol++) {
            const seen = {};
            for (let row = boxRow * 3; row < boxRow * 3 + 3; row++) {
                for (let col = boxCol * 3; col < boxCol * 3 + 3; col++) {
                    const num = board[row][col];
                    if (num !== 0) {
                        const key = `${row},${col}`;
                        if (seen[num]) {
                            errors.push({ row: row, col: col });
                            errors.push({ row: seen[num].row, col: seen[num].col });
                        } else {
                            seen[num] = { row: row, col: col };
                        }
                    }
                }
            }
        }
    }
    
    return errors;
}

// 数独求解算法（回溯法）
function solveSudokuAlgorithm(board) {
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            if (board[row][col] === 0) {
                for (let num = 1; num <= 9; num++) {
                    if (isValidMove(board, row, col, num)) {
                        board[row][col] = num;
                        
                        if (solveSudokuAlgorithm(board)) {
                            return true;
                        }
                        
                        board[row][col] = 0;
                    }
                }
                return false;
            }
        }
    }
    return true;
}

// 逐步求解数独算法
function solveSudokuStepByStepAlgorithm(board) {
    const steps = [];
    
    function solveWithSteps(b) {
        for (let row = 0; row < 9; row++) {
            for (let col = 0; col < 9; col++) {
                if (b[row][col] === 0) {
                    for (let num = 1; num <= 9; num++) {
                        if (isValidMove(b, row, col, num)) {
                            b[row][col] = num;
                            steps.push({ action: 'try', row: row, col: col, num: num });
                            
                            if (solveWithSteps(b)) {
                                return true;
                            }
                            
                            b[row][col] = 0;
                            steps.push({ action: 'backtrack', row: row, col: col, num: num });
                        }
                    }
                    return false;
                }
            }
        }
        return true;
    }
    
    solveWithSteps(board);
    return steps;
}

// 检查在特定位置放置数字是否有效
function isValidMove(board, row, col, num) {
    // 检查行
    for (let i = 0; i < 9; i++) {
        if (board[row][i] === num) {
            return false;
        }
    }
    
    // 检查列
    for (let i = 0; i < 9; i++) {
        if (board[i][col] === num) {
            return false;
        }
    }
    
    // 检查3x3子网格
    const boxRow = Math.floor(row / 3) * 3;
    const boxCol = Math.floor(col / 3) * 3;
    for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
            if (board[boxRow + i][boxCol + j] === num) {
                return false;
            }
        }
    }
    
    return true;
}

// 显示友好提示模态框
function showFriendlyAlert(message) {
    if (alertMessage && friendlyAlert) {
        alertMessage.textContent = message;
        friendlyAlert.classList.remove('hidden');
    } else {
        // 如果模态框元素不存在，回退到alert
        alert(message);
    }
}

// 隐藏友好提示模态框
function hideFriendlyAlert() {
    if (friendlyAlert) {
        friendlyAlert.classList.add('hidden');
    }
}

// 生成随机数独题目
function generateRandomSudoku() {
    console.log("点击了随机生成按钮");
    
    // 生成一个完整的数独解决方案
    const solution = generateSolvedSudoku();
    
    // 从完整解中挖洞，生成题目
    const puzzle = createPuzzleFromSolution(solution, 40); // 挖掉40个格子，中等难度
    
    // 清空当前棋盘但不隐藏数独区域
    sudokuBoard = Array(9).fill().map(() => Array(9).fill(0));
    originalBoard = Array(9).fill().map(() => Array(9).fill(0));
    updateBoardDisplay();
    statusMessage.textContent = '';
    difficultyDisplay.textContent = '难度: 未知';
    clearErrors();
    
    // 填充数独题目
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            sudokuBoard[row][col] = puzzle[row][col];
            originalBoard[row][col] = puzzle[row][col];
        }
    }
    
    // 更新显示
    updateBoardDisplay();
    updateDifficulty();
    
    // 显示提示信息
    updateStatusMessage('<i class="fas fa-check-circle mr-2"></i>已生成中等难度数独题目', 'status-message text-green-600 success-message', true, 3000);
}

// 将generateRandomSudoku函数绑定到window对象，使其可以在全局范围内访问
window.generateRandomSudoku = generateRandomSudoku;

// 生成已解决的数独
function generateSolvedSudoku() {
    // 创建空的9x9棋盘
    const board = Array(9).fill().map(() => Array(9).fill(0));
    
    // 填充对角线的3x3格子（这些格子之间互不影响）
    fillDiagonalBoxes(board);
    
    // 解决剩下的格子
    solveSudokuAlgorithm(board);
    
    return board;
}

// 填充对角线上的3x3格子
function fillDiagonalBoxes(board) {
    for (let i = 0; i < 9; i += 3) {
        fillBox(board, i, i);
    }
}

// 填充一个3x3格子
function fillBox(board, row, col) {
    const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    shuffleArray(numbers); // 随机打乱数组
    
    let idx = 0;
    for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
            board[row + i][col + j] = numbers[idx++];
        }
    }
}

// 随机打乱数组
function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
}

// 从完整解中创建题目
function createPuzzleFromSolution(solution, holes) {
    // 复制完整解
    const puzzle = JSON.parse(JSON.stringify(solution));
    
    // 创建所有可能的位置
    const positions = [];
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            positions.push({ row, col });
        }
    }
    
    // 随机打乱位置
    shuffleArray(positions);
    
    // 挖洞
    let removed = 0;
    for (const pos of positions) {
        if (removed >= holes) break;
        
        const row = pos.row;
        const col = pos.col;
        const backup = puzzle[row][col];
        puzzle[row][col] = 0;
        
        // 检查是否只有一个解
        if (hasOneSolution(puzzle)) {
            removed++;
        } else {
            // 如果不止一个解，恢复数字
            puzzle[row][col] = backup;
        }
    }
    
    return puzzle;
}

// 检查数独是否只有一个解
function hasOneSolution(board) {
    const boardCopy1 = JSON.parse(JSON.stringify(board));
    const boardCopy2 = JSON.parse(JSON.stringify(board));
    
    // 第一次求解
    const solved1 = solveSudokuAlgorithmUnique(boardCopy1);
    
    if (!solved1) return false;
    
    // 尝试用不同的顺序求解，看是否能得到不同的解
    // 通过反转数字尝试顺序
    const solved2 = solveSudokuAlgorithmUnique(boardCopy2, true);
    
    // 比较两个解是否相同
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            if (boardCopy1[row][col] !== boardCopy2[row][col]) {
                return false; // 有多解
            }
        }
    }
    
    return true; // 只有一个解
}

// 带有唯一解检查的数独求解算法（回溯法）
function solveSudokuAlgorithmUnique(board, reverse = false) {
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            if (board[row][col] === 0) {
                // 根据reverse参数决定尝试顺序
                const numbers = reverse ? [9, 8, 7, 6, 5, 4, 3, 2, 1] : [1, 2, 3, 4, 5, 6, 7, 8, 9];
                
                for (const num of numbers) {
                    if (isValidMove(board, row, col, num)) {
                        board[row][col] = num;
                        
                        if (solveSudokuAlgorithmUnique(board, reverse)) {
                            return true;
                        }
                        
                        board[row][col] = 0;
                    }
                }
                return false;
            }
        }
    }
    return true;
}

// 页面加载时自动加载配置
fetch('config.php')
    .then(response => response.json())
    .then(config => {
        console.log('App加载的配置:', config);  // 添加调试信息
        appConfig = config;
    })
    .catch(error => {
        console.error('从服务器加载配置失败:', error);
    });

// 添加OpenCV支持检查
function checkOpenCVSupport() {
    const openCVAvailable = typeof window !== 'undefined' && window.cv ? true : 
                           (typeof require !== 'undefined' ? require('./image-processing.js').isOpenCVAvailable() : false);
    
    if (openCVAvailable) {
        console.log('OpenCV支持已启用');
        showNotification('OpenCV支持已启用，图像处理功能增强', 'success');
    } else {
        console.log('OpenCV不可用，使用基础图像处理功能');
    }
    
    return openCVAvailable;
}

// 初始化应用时检查OpenCV支持
document.addEventListener('DOMContentLoaded', function() {
    createBoard();
    setupEventListeners();
    
    // 检查OpenCV支持
    checkOpenCVSupport();
    
    // 页面加载时自动加载配置
    fetch('config.php')
        .then(response => response.json())
        .then(config => {
            console.log('App加载的配置:', config);  // 添加调试信息
            appConfig = config;
        })
        .catch(error => {
            console.error('从服务器加载配置失败:', error);
        });

});

// 更新图像预处理函数，添加OpenCV支持
async function preprocessImageForOCR(canvas) {
    console.log('开始图像预处理');
    
    // 检查OpenCV是否可用
    const openCVAvailable = checkOpenCVSupport();
    
    if (openCVAvailable) {
        // 使用OpenCV进行高级图像处理
        try {
            // 这里应该调用OpenCV处理器
            console.log('使用OpenCV进行高级图像处理');
            showNotification('使用OpenCV进行图像处理...', 'info');
            
            // 模拟OpenCV处理过程
            // 实际使用中应该调用OpenCV函数
            await new Promise(resolve => setTimeout(resolve, 1000));
            
            showNotification('OpenCV图像处理完成', 'success');
        } catch (error) {
            console.error('OpenCV处理失败:', error);
            showNotification('OpenCV处理失败，使用基础处理方法', 'warning');
        }
    }
    
    // 基础图像处理
    const ctx = canvas.getContext('2d');
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    
    // 应用预处理
    const processedImageData = preprocessImageForOCR(imageData);
    ctx.putImageData(processedImageData, 0, 0);
    
    console.log('图像预处理完成');
    return canvas;
}

